import pygame
import sys
import threading
from flask import Flask, jsonify, request
from pygame.locals import *
import os
import time
import webbrowser

# 初始化Pygame
pygame.init()

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
BLUE = (0, 120, 215)

# 窗口尺寸
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600

class ServerGUI:
    def __init__(self):
        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption("音乐服务端")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont('simhei', 18)
        
        # 服务端状态
        self.song_queue = []
        self.manual_play = False
        self.is_playing = False
        self.queue_modified = False
        
        # 初始化Flask
        self.app = Flask(__name__)
        self.setup_routes()
        self.flask_thread = threading.Thread(target=self.run_flask, daemon=True)
        self.flask_thread.start()
        
        # GUI组件
        self.components = []
        self.init_ui()
        
    def setup_routes(self):
        @self.app.route('/add_song', methods=['POST'])
        def add_song():
            data = request.json
            self.song_queue.append(data)
            self.queue_modified = True
            return jsonify({'status': 'success'})

        @self.app.route('/playback_control', methods=['POST'])
        def playback_control():
            global manual_play, stop_flag
            command = request.json.get('command')
            
            if command == 'start':
                manual_play = True
                self.manual_event.set()
                stop_flag = False
                return jsonify({'status': '播放已启动'})
            elif command == 'stop':
                manual_play = False
                stop_flag = True
                self.manual_event.clear()
                pygame.mixer.music.stop()
                return jsonify({'status': '播放已停止'})
            return jsonify({'status': '无效指令'})

        @self.app.route('/get_queue', methods=['GET'])
        def get_queue():
            with self.queue_lock:
                # 过滤敏感信息并格式化输出
                safe_queue = []
                for song in self.song_queue:
                    item = {
                        'title': song.get('title', '未知歌曲'),
                        'artist': song.get('artist', '未知艺术家'),
                        'type': song['type'],
                        'duration': song.get('duration', 0)
                    }
                    if song['type'] == 'local':
                        item['path'] = os.path.basename(song.get('path', ''))
                    else:
                        item['url'] = song.get('url', '')
                    safe_queue.append(item)
                return jsonify(safe_queue)
        # 其他路由同之前实现...

    def init_ui(self):
        # 控制按钮
        self.play_btn = Button(20, 20, 100, 40, "播放" if not self.is_playing else "暂停", self.toggle_play)
        self.stop_btn = Button(140, 20, 100, 40, "停止", self.stop_play)
        self.add_local_btn = Button(20, 80, 120, 40, "添加本地", self.add_local)
        self.add_url_btn = Button(160, 80, 120, 40, "添加URL", self.add_url)
        
        # 歌曲列表
        self.list_box = ListBox(20, 140, 760, 400, self.song_queue)
        
        self.components.extend([self.play_btn, self.stop_btn, 
                              self.add_local_btn, self.add_url_btn,
                              self.list_box])

    def toggle_play(self):
        self.is_playing = not self.is_playing
        self.play_btn.text = "暂停" if self.is_playing else "播放"

    def stop_play(self):
        self.is_playing = False
        # 实际停止播放逻辑...

    def add_local(self):
        # 使用tkinter文件对话框
        from tkinter import Tk, filedialog
        root = Tk()
        root.withdraw()
        files = filedialog.askopenfilenames(
            title="选择音乐文件",
            filetypes=(("音频文件", "*.mp3 *.wav"), ("所有文件", "*.*"))
        )
        for f in files:
            self.song_queue.append({
                'type': 'local',
                'path': f,
                'title': os.path.basename(f)
            })
        self.queue_modified = True

    def add_url(self):
        # 弹出输入框
        input_box = InputDialog("输入歌曲URL", self.screen)
        url = input_box.run()
        if url:
            self.song_queue.append({
                'type': 'url',
                'url': url,
                'title': url[:30]
            })
            self.queue_modified = True

    def run_flask(self):
        self.app.run(host='0.0.0.0', port=5000)

    def run(self):
        running = True
        while running:
            self.screen.fill(WHITE)
            
            # 处理事件
            for event in pygame.event.get():
                if event.type == QUIT:
                    running = False
                elif event.type == MOUSEBUTTONDOWN:
                    for comp in self.components:
                        comp.handle_click(event.pos)
            
            # 更新组件
            if self.queue_modified:
                self.list_box.update_items(self.song_queue)
                self.queue_modified = False
            
            # 绘制组件
            for comp in self.components:
                comp.draw(self.screen)
            
            # 状态显示
            status_text = f"播放状态: {'播放中' if self.is_playing else '暂停'} | 队列长度: {len(self.song_queue)}"
            text_surf = self.font.render(status_text, True, BLACK)
            self.screen.blit(text_surf, (20, 560))
            
            pygame.display.flip()
            self.clock.tick(30)

        pygame.quit()
        sys.exit()

# GUI组件实现
class Button:
    def __init__(self, x, y, w, h, text, callback):
        self.rect = pygame.Rect(x, y, w, h)
        self.text = text
        self.callback = callback
        self.color = BLUE

    def draw(self, surface):
        pygame.draw.rect(surface, self.color, self.rect)
        font = pygame.font.SysFont('simhei', 16)
        text_surf = font.render(self.text, True, WHITE)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)

    def handle_click(self, pos):
        if self.rect.collidepoint(pos):
            self.callback()

class ListBox:
    def __init__(self, x, y, w, h, items):
        self.rect = pygame.Rect(x, y, w, h)
        self.items = items
        self.scroll_offset = 0
        self.item_height = 30

    def update_items(self, new_items):
        self.items = new_items

    def draw(self, surface):
        # 绘制背景
        pygame.draw.rect(surface, WHITE, self.rect)
        pygame.draw.rect(surface, GRAY, self.rect, 2)
        
        # 绘制项目
        visible_items = self.items[self.scroll_offset:self.scroll_offset+15]
        for i, item in enumerate(visible_items):
            y_pos = self.rect.y + 5 + i*self.item_height
            text = f"{i+1+self.scroll_offset}. {item['title']}"
            if item['type'] == 'local':
                text += f" ({os.path.basename(item['path'])})"
            else:
                text += f" ({item['url'][:20]}...)"
            font = pygame.font.SysFont('simhei', 14)
            text_surf = font.render(text, True, BLACK)
            surface.blit(text_surf, (self.rect.x+10, y_pos))

class InputDialog:
    def __init__(self, title, parent_surface):
        self.parent = parent_surface
        self.width = 400
        self.height = 150
        self.rect = pygame.Rect(
            (WINDOW_WIDTH-self.width)//2, 
            (WINDOW_HEIGHT-self.height)//2,
            self.width, self.height
        )
        self.font = pygame.font.SysFont('simhei', 18)
        self.title = title
        self.input_text = ""
        self.active = True

    def run(self):
        input_box = pygame.Rect(self.rect.x+20, self.rect.y+60, 360, 32)
        while True:
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_RETURN:
                        return self.input_text
                    elif event.key == K_BACKSPACE:
                        self.input_text = self.input_text[:-1]
                    else:
                        self.input_text += event.unicode
                elif event.type == MOUSEBUTTONDOWN:
                    if not input_box.collidepoint(event.pos):
                        return None

            # 绘制对话框
            self.parent.fill(BLACK)  # 半透明背景需要额外处理
            pygame.draw.rect(self.parent, WHITE, self.rect)
            
            # 标题
            title_surf = self.font.render(self.title, True, BLACK)
            self.parent.blit(title_surf, (self.rect.x+20, self.rect.y+20))
            
            # 输入框
            pygame.draw.rect(self.parent, GRAY, input_box, 2)
            text_surf = self.font.render(self.input_text, True, BLACK)
            self.parent.blit(text_surf, (input_box.x+5, input_box.y+5))
            
            pygame.display.flip()

if __name__ == '__main__':
    server = ServerGUI()
    server.run()